use crate::vm::VirtualMachine;
use crate::compiler::Compiler;
use crate::vm::Value;
use std::fs;
use std::os::raw::{c_char, c_int};

// 示例API模块，展示如何使用Result返回错误
use crate::error::{Result, PipitError};

pub struct Api {
    compiler: Compiler,
    vm: VirtualMachine,
}

impl Api {
    /// 创建 API 实例
    pub fn new() -> Self {
        Api {
            compiler: Compiler::new(),
            vm: VirtualMachine::new(),
        }
    }
    
    /// 运行代码，返回Result表示可能的错误
    pub fn run_code(&mut self, source: &str) -> Result<()> {
        // 检查源码是否为空
        if source.is_empty() {
            return Err(PipitError::CompileError("Source code is empty".to_string()));
        }
        
        // 编译源码
        let bytecode = self.compiler.compile(source)
            .map_err(|e| PipitError::CompileError(format!("Compilation failed: {:?}", e)))?;
        
        // 设置虚拟机字节码
        self.vm = VirtualMachine::with_bytecode(bytecode);
        
        // 执行代码
        self.vm.execute()
            .map_err(|e| PipitError::RuntimeError(format!("Execution failed: {:?}", e)))?;
        
        Ok(())
    }
    
    /// 加载并运行文件
    pub fn load_and_run(&mut self, filename: &str) -> Result<()> {
        // 检查文件扩展名
        if !filename.ends_with(".pi") {
            return Err(PipitError::CompileError(
                format!("Pipit source files must have .pi extension, got: {}", filename)
            ));
        }
        
        // 读取文件
        let source = fs::read_to_string(filename)
            .map_err(|e| match e.kind() {
                std::io::ErrorKind::NotFound => {
                    PipitError::FileNotFoundError(format!("File '{}' not found", filename))
                },
                std::io::ErrorKind::PermissionDenied => {
                    PipitError::PermissionError(format!("Permission denied for file '{}'", filename))
                },
                _ => PipitError::IoError(e),
            })?;
        
        // 运行代码
        self.run_code(&source)?;
        Ok(())
    }
    
    /// 获取模块注册信息（可变引用）
    pub fn get_module_registry(&mut self) -> &mut Compiler {
        &mut self.compiler
    }
}

// 原生函数：获取数组长度
fn native_array_length(vm: &mut VirtualMachine) {
    if vm.stack_len() < 1 {
        return;
    }
    
    let array = vm.pop_stack().unwrap();
    let length = match array {
        Value::Array(arr) => arr.len() as i32,
        _ => 0, // 非数组类型返回0
    };
    
    let _ = vm.push_stack(Value::Integer(length));
}

/// 模块结构

// C接口函数
#[no_mangle]
pub unsafe extern "C" fn execute_code(source: *const c_char) {
    use std::ffi::CStr;
    
    let source_cstr = unsafe { CStr::from_ptr(source) };
    let source_str = source_cstr.to_str().unwrap();
    
    println!("C interface: execute_code");
    let mut api = Api::new();
    match api.run_code(source_str) {
        Ok(()) => println!("Code executed successfully"),
        Err(e) => eprintln!("Error executing code: {}", e),
    }
}

#[no_mangle]
pub extern "C" fn get_stack(_size: *mut c_int) -> *mut c_int {
    // 实现获取堆栈的C接口
    std::ptr::null_mut()
}

#[no_mangle]
pub unsafe extern "C" fn load_and_run(filename: *const c_char) {
    use std::ffi::CStr;
    
    let filename_cstr = unsafe { CStr::from_ptr(filename) };
    let filename_str = filename_cstr.to_str().unwrap();
    
    println!("C interface: load_and_run");
    let mut api = Api::new();
    let result = api.load_and_run(filename_str);
    
    match result {
        Ok(()) => println!("Successfully executed file: {}", filename_str),
        Err(e) => eprintln!("Error executing file: {}", e),
    }
}
